﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Input;
using ViewMaker;
using ViewMaker.Core.Controls;
using ViewMaker.Core.Utils;

namespace ViewMaker.Core.Tests
{
    [View(ViewControlType.TabControl)]
    [ViewProperty(TabControlViewControl.Properties.HorizontalAlignment, LayoutHorizontalAlignment.Stretch)]
    [ViewProperty(TabControlViewControl.Properties.TabStripPlacement, LayoutDock.Left)]
#if SILVERLIGHT
    [ViewProperty(TabControlViewControl.Properties.Width, 600)]
#endif
    public class SampleViewModel : ViewModelBase
    {
        public class DataItem
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public DateTime Date { get; set; }
            public bool OnOff { get; set; }

            public static List<DataItem> CreateData(int size)
            {
                var list = new List<DataItem>();
                for (int i = 0; i < size; i++)
                {
                    list.Add(new DataItem
                    {
                        Id = i,
                        Name = "Name" + i.ToString(),
                        Date = DateTime.Now,
                        OnOff = (i % 3) == 0
                    });
                }
                return list;
            }
        }


        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public class LabelSample
        {
            [View(ViewControlType.Label)]
            [ViewProperty(LabelViewControl.Properties.StringFormat, "[{0}]")]
            public string Label1 { get; set; }

            [View(ViewControlType.Label)]
            [ViewProperty(LabelViewControl.Properties.StringFormat, "yyyy/MM/dd(ddd)")]
            public DateTime Label2 { get; set; }


            [View(ViewControlType.Label)]
            [ViewProperty(LabelViewControl.Properties.StringFormat, "c")]
            [ViewProperty(LabelViewControl.Properties.HorizontalContentAlignment, LayoutHorizontalAlignment.Right)]
            public int Label3 { get; set; }


            [View(ViewControlType.Label)]
            [ViewProperty(LabelViewControl.Properties.Width, 200)]
            [ViewProperty(LabelViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(LabelViewControl.Properties.Background, "Azure")]
            public string Label4 { get; set; }

            public LabelSample()
            {
                Label1 = "Hello!!";
                Label2 = DateTime.Now;
                Label3 = 100;
                Label4 = @"first line
second line";
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public class TextBoxSample : ViewModelBase
        {

            [View(ViewControlType.TextBox)]
            [ViewProperty(TextBoxViewControl.Properties.StringFormat, "[{0}]")]
            public string TextBox1 { get; set; }

            [View(ViewControlType.TextBox)]
            [ViewProperty(TextBoxViewControl.Properties.StringFormat, "yyyy/MM/dd(ddd)")]
            public DateTime TextBox2 { get; set; }

            [View(ViewControlType.TextBox)]
            [ViewProperty(TextBoxViewControl.Properties.StringFormat, "c")]
            [ViewProperty(TextBoxViewControl.Properties.IsReadOnly, true)]
            [ViewProperty(TextBoxViewControl.Properties.TextAlignment, LayoutHorizontalAlignment.Right)]
            public int TextBox3 { get; private set; }

            [View(ViewControlType.TextBox)]
            [ViewProperty(TextBoxViewControl.Properties.IsMultiline, true)]
            [ViewProperty(TextBoxViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(TextBoxViewControl.Properties.Background, "Azure")]
            [ViewProperty(TextBoxViewControl.Properties.Width, 250)]
            public string TextBox4 { get; set; }

            [View(ViewControlType.TextBox)]
            [ViewProperty(TextBoxViewControl.Properties.IsEmptyAsNull, true)]
            [ViewProperty(TextBoxViewControl.Properties.LostFocusCommand, "LostFocusCommand")]
            public string TextBox5 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.EnterKeyCommand, "EnterKeyCommand")]
            public string TextBox6
            {
                get { return _textBox6; }
                set { _textBox6 = value; OnPropertyChanged("TextBox6"); }
            }
            private string _textBox6;

            [Browsable(false)]
            public ICommand LostFocusCommand
            {
                get { return this.CreateCommand(() => TextBox6 = (TextBox5 ?? "(null)")); }
            }

            [Browsable(false)]
            public ICommand EnterKeyCommand
            {
                get { return this.CreateCommand(() => TextBox6 = TextBox6.ToUpper()); }
            }

            public TextBoxSample()
            {
                TextBox1 = "Hello!!";
                TextBox2 = DateTime.Now;
                TextBox3 = 100;
                TextBox4 = @"first line
second line";
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        [ViewLayoutGeneratorProvider("Generate")]
        public class ComboBoxSample : ViewModelBase
        {
            [View(ViewControlType.ComboBox)]
            [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ItemSource1")]
            [ViewProperty(ComboBoxViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand1")]
            public string ComboBox1 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public string ComboBox1Value { get; set; }

            [View(ViewControlType.ComboBox)]
            [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ItemSource2")]
            [ViewProperty(ComboBoxViewControl.Properties.DisplayMemberPath, "Value")]
            [ViewProperty(ComboBoxViewControl.Properties.SelectedValuePath, "Key")]
            [ViewProperty(ComboBoxViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(ComboBoxViewControl.Properties.Background, "Azure")]
            [ViewProperty(ComboBoxViewControl.Properties.Width, 250)]
            [ViewProperty(ComboBoxViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand2")]
            public string ComboBox2 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public int ComboBox2Value { get; set; }

            [View(ViewControlType.ComboBox)]
            [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "ItemSource1")]
            [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
            [ViewProperty(ComboBoxViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(ComboBoxViewControl.Properties.Background, "Azure")]
            [ViewProperty(ComboBoxViewControl.Properties.Width, 250)]
            [ViewProperty(ComboBoxViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand3")]
            public string ComboBox3 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public string ComboBox3Value { get; set; }

            [View(ViewControlType.ComboBox)]
            public string ComboBox4 { get; set; }

            [Browsable(false)]
            public List<string> ItemSource1
            {
                get { return new List<string>(new string[] { "ONE", "TWO", "THREE" }); }
            }

            [Browsable(false)]
            public Dictionary<int, string> ItemSource2
            {
                get
                {
                    var dict = new Dictionary<int, string>();
                    dict.Add(1, "One");
                    dict.Add(2, "Two");
                    dict.Add(3, "Three");
                    return dict;
                }
            }

            [Browsable(false)]
            public ICommand SelectionChangedCommand1 { get { return CreateCommand(SelectionChanged1); } }
            private void SelectionChanged1(object x)
            {
                var data = (object[])x;
                ComboBox1Value = (string)data[0];
                OnPropertyChanged("ComboBox1Value");
            }
            [Browsable(false)]
            public ICommand SelectionChangedCommand2 { get { return CreateCommand(SelectionChanged2); } }
            private void SelectionChanged2(object x)
            {
                var data = (object[])x;
                ComboBox2Value = ((KeyValuePair<int, string>)data[0]).Key;
                OnPropertyChanged("ComboBox2Value");
            }
            [Browsable(false)]
            public ICommand SelectionChangedCommand3 { get { return CreateCommand(SelectionChanged3); } }
            private void SelectionChanged3(object x)
            {
                var data = (object[])x;
                ComboBox3Value = (string)data[0];
                OnPropertyChanged("ComboBox3Value");
            }

            public static ViewLayoutItem Generate()
            {
                var svc = ServiceLocator.GetService<IViewLayoutGenerator>();
                var layout = svc.Generate(typeof(ComboBoxSample), LayoutGenerateFlag.All & ~LayoutGenerateFlag.StaticProvider);

                var items = layout.FindChild("ComboBox4").GetControl<ComboBoxViewControl>().ItemsList;
                items.Add("one");
                items.Add("two");
                items.Add("three");
                return layout;
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        [ViewLayoutGeneratorProvider("Generate")]
        public class ListBoxSample : ViewModelBase
        {
            [View(ViewControlType.ListBox)]
            [ViewProperty(ListBoxViewControl.Properties.ItemsSource, "ItemSource1")]
            [ViewProperty(ListBoxViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand1")]
            public string ListBox1 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public string ListBox1Value { get; set; }

            [View(ViewControlType.ListBox)]
            [ViewProperty(ListBoxViewControl.Properties.ItemsSource, "ItemSource2")]
            [ViewProperty(ListBoxViewControl.Properties.DisplayMemberPath, "Value")]
            [ViewProperty(ListBoxViewControl.Properties.SelectedValuePath, "Key")]
            [ViewProperty(ListBoxViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(ListBoxViewControl.Properties.Background, "Azure")]
            [ViewProperty(ListBoxViewControl.Properties.Width, 250)]
            [ViewProperty(ListBoxViewControl.Properties.Height, 150)]
            [ViewProperty(ListBoxViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand2")]
            public string ListBox2 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public int ListBox2Value { get; set; }

            [View(ViewControlType.ListBox)]
            [ViewProperty(ListBoxViewControl.Properties.FontSize, 20.0)]
            [ViewProperty(ListBoxViewControl.Properties.Height, 100)]
            public string ListBox3 { get; set; }

            [View(ViewControlType.ListBox)]
            [ViewProperty(ListBoxViewControl.Properties.ItemsSource, "ItemSource2")]
            [ViewProperty(ListBoxViewControl.Properties.DisplayMemberPath, "Value")]
            public KeyValuePair<int, string> ListBox4 { get; set; }

            [Browsable(false)]
            public List<string> ItemSource1
            {
                get { return new List<string>(new string[] { "ONE", "TWO", "THREE" }); }
            }

            [Browsable(false)]
            public Dictionary<int, string> ItemSource2
            {
                get
                {
                    var dict = new Dictionary<int, string>();
                    dict.Add(1, "One");
                    dict.Add(2, "Two");
                    dict.Add(3, "Three");
                    return dict;
                }
            }

            [Browsable(false)]
            public ICommand SelectionChangedCommand1 { get { return CreateCommand(SelectionChanged1); } }
            private void SelectionChanged1(object x)
            {
                var data = (object[])x;
                ListBox1Value = (string)data[0];
                OnPropertyChanged("ListBox1Value");
            }
            [Browsable(false)]
            public ICommand SelectionChangedCommand2 { get { return CreateCommand(SelectionChanged2); } }
            private void SelectionChanged2(object x)
            {
                var data = (object[])x;
                ListBox2Value = ((KeyValuePair<int, string>)data[0]).Key;
                OnPropertyChanged("ListBox2Value");
            }

            public static ViewLayoutItem Generate()
            {
                var svc = ServiceLocator.GetService<IViewLayoutGenerator>();
                var layout = svc.Generate(typeof(ListBoxSample), LayoutGenerateFlag.All & ~LayoutGenerateFlag.StaticProvider);

                var items = layout.FindChild("ListBox3").GetControl<ListBoxViewControl>().ItemsList;
                items.Add("one");
                items.Add("two");
                items.Add("three");
                items.Add("four");
                items.Add("five");
                items.Add("six");
                return layout;
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        [ViewLayoutGeneratorProvider("Generate")]
        public class RadioButtonListSample : ViewModelBase
        {
            [View(ViewControlType.RadioButtonList)]
            [ViewProperty(RadioButtonListViewControl.Properties.ItemsSource, "ItemSource1")]
            [ViewProperty(RadioButtonListViewControl.Properties.Orientation, LayoutOrientation.Horizontal)]
            [ViewProperty(RadioButtonListViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand1")]
            public string RadioButtonList1 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public string RadioButtonList1Value { get; set; }

            [View(ViewControlType.RadioButtonList)]
            [ViewProperty(RadioButtonListViewControl.Properties.ItemsSource, "ItemSource2")]
            [ViewProperty(RadioButtonListViewControl.Properties.DisplayMemberPath, "Value")]
            [ViewProperty(RadioButtonListViewControl.Properties.SelectedValuePath, "Key")]
            [ViewProperty(RadioButtonListViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand2")]
            public string RadioButtonList2 { get; set; }

            [View(ViewControlType.Label)]
            [Display(Name = "Seleced Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public int RadioButtonList2Value { get; set; }

            [View(ViewControlType.RadioButtonList)]
            [ViewProperty(RadioButtonListViewControl.Properties.FontSize, 14.0)]
            [ViewProperty(RadioButtonListViewControl.Properties.ItemWidth, 150)]
            [ViewProperty(RadioButtonListViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(RadioButtonListViewControl.Properties.Background, "Azure")]
            [ViewProperty(RadioButtonListViewControl.Properties.Orientation, LayoutOrientation.Horizontal)]
            public string RadioButtonList3 { get; set; }

            [Browsable(false)]
            public List<string> ItemSource1
            {
                get { return new List<string>(new string[] { "ONE", "TWO", "THREE" }); }
            }

            [Browsable(false)]
            public Dictionary<int, string> ItemSource2
            {
                get
                {
                    var dict = new Dictionary<int, string>();
                    dict.Add(1, "One");
                    dict.Add(2, "Two");
                    dict.Add(3, "Three");
                    return dict;
                }
            }

            [Browsable(false)]
            public ICommand SelectionChangedCommand1 { get { return CreateCommand(SelectionChanged1); } }
            private void SelectionChanged1(object x)
            {
                var data = (object[])x;
                RadioButtonList1Value = (string)data[0];
                OnPropertyChanged("RadioButtonList1Value");
            }
            [Browsable(false)]
            public ICommand SelectionChangedCommand2 { get { return CreateCommand(SelectionChanged2); } }
            private void SelectionChanged2(object x)
            {
                var data = (object[])x;
                RadioButtonList2Value = ((KeyValuePair<int, string>)data[0]).Key;
                OnPropertyChanged("RadioButtonList2Value");
            }

            public static ViewLayoutItem Generate()
            {
                var svc = ServiceLocator.GetService<IViewLayoutGenerator>();
                var layout = svc.Generate(typeof(RadioButtonListSample), LayoutGenerateFlag.All & ~LayoutGenerateFlag.StaticProvider);

                var items = layout.FindChild("RadioButtonList3").GetControl<RadioButtonListViewControl>().ItemsList;
                items.Add("one");
                items.Add("two");
                items.Add("three");
                return layout;
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        [ViewProperty(StackPanelViewControl.Properties.ItemMargin, "20")]
        [ViewLayoutGeneratorProvider("Generate")]
        public class ItemsControlSample : ViewModelBase
        {
            [View(ViewControlType.ItemsControl)]
            public List<DataItem> ItemsControl1 { get; set; }

            [View(ViewControlType.ItemsControl)]
            [ViewProperty(ItemsControlViewControl.Properties.Height, 150)]
            [ViewProperty(ItemsControlViewControl.Properties.HasScrollViewer, true)]
            public List<DataItem> ItemsControl2 { get; set; }

            public ItemsControlSample()
            {
                ItemsControl1 = DataItem.CreateData(3);
                ItemsControl2 = DataItem.CreateData(10);
            }

            public static ViewLayoutItem Generate()
            {
                var svc = ServiceLocator.GetService<IViewLayoutGenerator>();
                var layout = svc.Generate(typeof(ItemsControlSample), LayoutGenerateFlag.All & ~LayoutGenerateFlag.StaticProvider);
                var item1 = layout.FindChild("ItemsControl1").InsertChild(null, ViewControlType.Grid);
                item1.GetControl<GridViewControl>().ItemColumnSize = 4;
                var item2 = layout.FindChild("ItemsControl2").InsertChild(null, ViewControlType.Grid);
                item2.GetControl<GridViewControl>().ItemColumnSize = 4;
                return layout;
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        [ViewLayoutGeneratorProvider("Generate")]
        public class CheckBoxSample : ViewModelBase
        {
            [View(ViewControlType.CheckBox)]
            public bool CheckBox1 { get; set; }

            [View(ViewControlType.CheckBox)]
            [ViewProperty(CheckBoxViewControl.Properties.Content, "CheckBox2Content")]
            [ViewProperty(CheckBoxViewControl.Properties.IsThreeState, true)]
            [ViewProperty(CheckBoxViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(CheckBoxViewControl.Properties.Background, "Azure")]
            [ViewProperty(CheckBoxViewControl.Properties.CheckedUncheckedCommand, "CheckedUncheckedCommand2")]
            public bool? CheckBox2 { get; set; }

            [Browsable(false)]
            public string CheckBox2Content { get { return "nullable"; } }

            [Browsable(false)]
            public ICommand CheckedUncheckedCommand2 { get { return CreateCommand(CheckedUnchecked2); } }
            private void CheckedUnchecked2(object x)
            {
                var data = (object[])x;
                CheckBox2Value = CheckBox2 == null ? "(null)" : CheckBox2.Value.ToString();
                OnPropertyChanged("CheckBox2Value");
            }

            [View(ViewControlType.Label)]
            [Display(Name = "Current Value")]
            [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public string CheckBox2Value { get; set; }

        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public class DatePickerSample : ViewModelBase
        {
            [View(ViewControlType.DatePicker)]
            public string DatePicker1 { get; set; }

            [View(ViewControlType.DatePicker)]
            [ViewProperty(DatePickerViewControl.Properties.SelectedDateFormat, "Long")]
            public DateTime DatePicker2 { get; set; }

            [View(ViewControlType.DatePicker)]
            [ViewProperty(DatePickerViewControl.Properties.Width, 200)]
            [ViewProperty(DatePickerViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(DatePickerViewControl.Properties.Background, "Azure")]
            [ViewProperty(DatePickerViewControl.Properties.SelectedDateFormat, "Short")]
            public DateTime? DatePicker3 { get; set; }

            public DatePickerSample()
            {
                DatePicker1 = "2000/1/1";
                DatePicker2 = DateTime.Now;
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public class ButtonSample : ViewModelBase
        {
            public bool ButtonEnable
            {
                get { return _buttonEnable; }
                set { _buttonEnable = value; OnPropertyChanged(null); }
            }
            private bool _buttonEnable;


            [View(ViewControlType.Button)]
            public ICommand Button1 { get { return CreateCommand(() => this.ShowMessage("Button1"), (x)=>ButtonEnable); } }

            [View(ViewControlType.Button)]
#if !UNITTEST
#if !SILVERLIGHT
            [ViewProperty(ButtonViewControl.Properties.ImageSource, "/ViewMaker.SampleApplication;component/ButtonImage.png")]
#else
            [ViewProperty(ButtonViewControl.Properties.ImageSource, "/SilverlightViewMaker.SampleApplication;component/ButtonImage.png")]
#endif
#endif
            public ICommand Button2 { get { return CreateCommand(() => this.ShowMessage("Button2"), (x) => ButtonEnable); } }

            [View(ViewControlType.Button)]
            [ViewProperty(ButtonViewControl.Properties.Width, 200)]
            [ViewProperty(ButtonViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(ButtonViewControl.Properties.Background, "Azure")]
            public ICommand Button3 { get { return CreateCommand(() => this.ShowMessage("Button3"), (x) => ButtonEnable); } }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public class HyperlinkSample : ViewModelBase
        {
            [View(ViewControlType.Hyperlink)]
            public string Hyperlink1 { get; set; }

            [View(ViewControlType.Hyperlink)]
            [ViewProperty(HyperlinkViewControl.Properties.NavigateUri, "Hyperlink2Url")]
            public string Hyperlink2 { get; set; }

            [Browsable(false)]
            public string Hyperlink2Url { get; set; }

            [View(ViewControlType.Hyperlink)]
            [ViewProperty(HyperlinkViewControl.Properties.Command, "Hyperlink3Command")]
            [ViewProperty(HyperlinkViewControl.Properties.Width, 200)]
            [ViewProperty(HyperlinkViewControl.Properties.Foreground, "Blue")]
            [ViewProperty(HyperlinkViewControl.Properties.Background, "Azure")]
            public string Hyperlink3 { get; set; }

            [Browsable(false)]
            public ICommand Hyperlink3Command { get { return CreateCommand(() => this.ShowMessage("Hyperlink3")); } }

            public HyperlinkSample()
            {
                Hyperlink1 = "http://viewmaker.codeplex.com/";
                Hyperlink2 = "ViewMaker";
                Hyperlink2Url = "http://viewmaker.codeplex.com/";
                Hyperlink3 = "Message";
            }
        }

        [View(ViewControlType.Grid)]
        [ViewProperty(GridViewControl.Properties.HeaderBackground, "Azure")]
        [ViewProperty(GridViewControl.Properties.ItemMargin, "10")]
        [ViewProperty("ShowGridLines", true)]
        public class HeaderSample : ViewModelBase
        {
            [Display(Name = "Flat mode")]
            [ViewProperty(HeaderViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Flat)]
            [ViewProperty(HeaderViewControl.Properties.HeaderHorizontalContentAlignment, LayoutHorizontalAlignment.Right)]
            [ViewProperty(GridViewControl.Properties.HeaderWidth, 150)]
            [ViewProperty(HeaderViewControl.Properties.Height, 50)]
            public string Header1 { get; set; }

            [Display(Name = "Left mode")]
            [ViewProperty(HeaderViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            [ViewProperty(HeaderViewControl.Properties.ColumnSpan, 0)]
            [ViewProperty(HeaderViewControl.Properties.Height, 50)]
            [ViewProperty(HeaderViewControl.Properties.HeaderWidth, 100)]
            [ViewProperty(HeaderViewControl.Properties.HeaderHeight, 50)]
            [ViewProperty(GridViewControl.Properties.HeaderFontSize, 14.0)]
            public string Header2 { get; set; }

            [Display(Name = "Top mode")]
            [ViewProperty(HeaderViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Top)]
            [ViewProperty(HeaderViewControl.Properties.ColumnSpan, 0)]
            [ViewProperty(HeaderViewControl.Properties.HeaderVerticalAlignment, LayoutVerticalAlignment.Bottom)]
            [ViewProperty(HeaderViewControl.Properties.HeaderForeground, "Blue")]
            [ViewProperty(HeaderViewControl.Properties.Height, 50)]
            public string Header3 { get; set; }

            [ViewProperty(HeaderViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
            [ViewProperty(HeaderViewControl.Properties.ColumnSpan, 0)]
            [ViewProperty(HeaderViewControl.Properties.Height, 50)]
            public string Header4 { get; set; }

            public HeaderSample()
            {
                Header1 = "some text";
                Header2 = "some text";
                Header3 = "some text";
                Header4 = "Hidden mode";
            }
        }

        [View(ViewControlType.Canvas)]
        [ViewProperty(CanvasViewControl.Properties.HeaderBackground, "Azure")]
        [ViewProperty(CanvasViewControl.Properties.HeaderWidth, 50)]
        [ViewProperty(CanvasViewControl.Properties.HorizontalAlignment, LayoutHorizontalAlignment.Stretch)]
        [ViewProperty(CanvasViewControl.Properties.VerticalAlignment, LayoutVerticalAlignment.Stretch)]
        [ViewProperty(CanvasViewControl.Properties.LoadCommand, "LoadCommand")]
        [ViewProperty(CanvasViewControl.Properties.UnloadCommand, "UnloadCommand")]
        [ViewProperty("MinHeight", 250)]
        public class CanvasSample : ViewModelBase
        {
            public string Item1 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Top)]
            [ViewProperty(TextBoxViewControl.Properties.CanvasLeft, 30)]
            [ViewProperty(TextBoxViewControl.Properties.CanvasTop, 30)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 200)]
            [ViewProperty(TextBoxViewControl.Properties.Height, 50)]
            public string Item2 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            [ViewProperty(TextBoxViewControl.Properties.HeaderHorizontalContentAlignment, LayoutHorizontalAlignment.Right)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 20)]
            [ViewProperty(TextBoxViewControl.Properties.CanvasLeft, 240)]
            [ViewProperty(TextBoxViewControl.Properties.CanvasTop, 75)]
            public bool Item3 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.CanvasLeft, 250)]
            [ViewProperty(TextBoxViewControl.Properties.CanvasTop, 20)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 100)]
            public DateTime Item4 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.CanvasLeft, 40)]
            [ViewProperty(TextBoxViewControl.Properties.CanvasTop, 120)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 400)]
            [ViewProperty(TextBoxViewControl.Properties.Height, 100)]
            public List<DataItem> Item5 { get; set; }

            [Browsable(false)]
            public ICommand LoadCommand { get { return CreateCommand(Init); } }
            [Browsable(false)]
            public ICommand UnloadCommand { get { return CreateCommand(() => Debug.WriteLine("Unload " + this.GetType().Name)); } }

            public void Init()
            {
                Item1 = "some Text";
                Item2 = "some Text";
                Item5 = DataItem.CreateData(30);
                OnPropertyChanged(null);
            }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderBackground, "Azure")]
        [ViewProperty(StackPanelViewControl.Properties.HeaderWidth, 50)]
        [ViewProperty(StackPanelViewControl.Properties.HorizontalAlignment, LayoutHorizontalAlignment.Stretch)]
        [ViewProperty(StackPanelViewControl.Properties.VerticalAlignment, LayoutVerticalAlignment.Stretch)]
        [ViewProperty(StackPanelViewControl.Properties.HasHeader, true)]
        [ViewProperty(StackPanelViewControl.Properties.LoadCommand, "LoadCommand")]
        [ViewProperty(StackPanelViewControl.Properties.UnloadCommand, "UnloadCommand")]
        [ViewProperty("MinHeight", 150)]
        public class StackPanelSample : ViewModelBase
        {
            public string Item1 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Top)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 200)]
            [ViewProperty(TextBoxViewControl.Properties.Height, 50)]
            public string Item2 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            [ViewProperty(TextBoxViewControl.Properties.HeaderHorizontalContentAlignment, LayoutHorizontalAlignment.Right)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 20)]
            public bool Item3 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.Width, 100)]
            public DateTime Item4 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.Height, 100)]
            public List<DataItem> Item5 { get; set; }

            [Browsable(false)]
            public ICommand LoadCommand { get { return CreateCommand(Init); } }
            [Browsable(false)]
            public ICommand UnloadCommand { get { return CreateCommand(() => Debug.WriteLine("Unload " + this.GetType().Name)); } }

            public void Init()
            {
                Item1 = "some Text";
                Item2 = "some Text";
                Item5 = DataItem.CreateData(30);
                OnPropertyChanged(null);
            }
        }

        [View(ViewControlType.Grid)]
        [ViewProperty(GridViewControl.Properties.HeaderBackground, "Azure")]
        [ViewProperty(GridViewControl.Properties.ItemColumnSize, 2)]
        [ViewProperty(GridViewControl.Properties.HorizontalAlignment, LayoutHorizontalAlignment.Stretch)]
        [ViewProperty(GridViewControl.Properties.VerticalAlignment, LayoutVerticalAlignment.Stretch)]
        [ViewProperty(GridViewControl.Properties.LoadCommand, "LoadCommand")]
        [ViewProperty(GridViewControl.Properties.UnloadCommand, "UnloadCommand")]
        [ViewProperty("MinHeight", 150)]
#if SILVERLIGHT
        [ViewProperty(GridViewControl.Properties.Height, 300)]
#endif
        public class GridSample : ViewModelBase
        {
            public string Item1 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Top)]
            [ViewProperty(TextBoxViewControl.Properties.Height, 50)]
            [ViewProperty(TextBoxViewControl.Properties.ColumnSpan, 0)]
            public string Item2 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            [ViewProperty(TextBoxViewControl.Properties.HeaderHorizontalContentAlignment, LayoutHorizontalAlignment.Right)]
            [ViewProperty(TextBoxViewControl.Properties.Width, 20)]
            public bool Item3 { get; set; }

            [ViewProperty(TextBoxViewControl.Properties.Width, 100)]
            [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)]
            public DateTime Item4 { get; set; }

            [View(ViewControlType.DataGrid)]
            public List<DataItem> Item5 { get; set; }

            [Browsable(false)]
            public ICommand LoadCommand { get { return CreateCommand(Init); } }
            [Browsable(false)]
            public ICommand UnloadCommand { get { return CreateCommand(() => Debug.WriteLine("Unload " + this.GetType().Name)); } }

            public void Init()
            {
                Item1 = "some Text";
                Item2 = "some Text";
                Item5 = DataItem.CreateData(30);
                OnPropertyChanged(null);
            }
        }

        [View(ViewControlType.Grid)]
        [ViewProperty("MinHeight", 150)]
        public class DataGridSample : ViewModelBase
        {

            public class GridItem
            {
                [ViewProperty(DataGridTextColumnViewElement.Properties.IsReadOnly, true)]
                [ViewProperty(DataGridTextColumnViewElement.Properties.StringFormat, "[{0}]")]
                public int Id { get; set; }

                [ViewProperty(DataGridTextColumnViewElement.Properties.Width, 100)]
                [ViewProperty(DataGridTextColumnViewElement.Properties.TextAlignment, LayoutHorizontalAlignment.Right)]
                [ViewProperty(DataGridTextColumnViewElement.Properties.IsEmptyAsNull, true)]
                public string Group { get; set; }

                [View(ViewControlType.DataGridComboBoxColumn)]
                [ViewProperty(DataGridComboBoxColumnViewElement.Properties.ItemsSource, "NameList")]
                public string Name { get; set; }

                [View(ViewControlType.DataGridComboBoxColumn)]
                [ViewProperty(DataGridComboBoxColumnViewElement.Properties.ItemsSource, "DateList")]
                [ViewProperty(DataGridComboBoxColumnViewElement.Properties.DisplayMemberPath, "Key")]
                [ViewProperty(DataGridComboBoxColumnViewElement.Properties.SelectedValuePath, "Value")]
                public DateTime Date { get; set; }

                [ViewProperty(DataGridColumnViewElement.Properties.Width, 100)]
                public bool OnOff { get; set; }

                [ViewProperty(DataGridCheckBoxColumnViewElement.Properties.IsThreeState, true)]
                public bool? ThreeState { get; set; }

                [Browsable(false)]
                public List<string> NameList { get { return new List<string> { "One", "Two", "Three" }; } }

                [Browsable(false)]
                public Dictionary<string, DateTime> DateList
                {
                    get
                    {
                        return new Dictionary<string, DateTime> { 
                           {"yestaday", DateTime.Today.AddDays(-1) },
                           {"today", DateTime.Today },
                           {"tomorrow", DateTime.Today.AddDays(1) }
                        };
                    }
                }

                public static List<GridItem> CreateData(int size)
                {
                    var list = new List<GridItem>();
                    for (int i = 0; i < size; i++)
                    {
                        list.Add(new GridItem
                        {
                            Id = i,
                            Name = "One",
                            Date = DateTime.Today,
                            OnOff = (i % 3) == 0
                        });
                    }
                    return list;
                }
            }

            public string DoubleClickItem
            {
                get { return _doubleClickItem; }
                set { _doubleClickItem = value; OnPropertyChanged("DoubleClickItem"); }
            }
            private string _doubleClickItem;

            public string SelectionChangedItem
            {
                get { return _selectionChangedItem; }
                set { _selectionChangedItem = value; OnPropertyChanged("SelectionChangedItem"); }
            }
            private string _selectionChangedItem;


            [View(ViewControlType.DataGrid)]
            [ViewProperty(DataGridViewControl.Properties.SelectedItem, "SelectedData")]
            [ViewProperty(DataGridViewControl.Properties.DoubleClickCommand, "DoubleClickCommand")]
            [ViewProperty(DataGridViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand")]
            public List<GridItem> DataGrid1 { get; set; }

            [Browsable(true)]
            public GridItem SelectedData
            {
                get { return _selectedData; }
                set { _selectedData = value; OnPropertyChanged("SelectedData"); }
            }
            private GridItem _selectedData;

            [Browsable(false)]
            public ICommand DoubleClickCommand { get { return CreateCommand(DoubleClick); } }
            private void DoubleClick(object arg)
            {
                var item = arg as GridItem;
                if (item != null)
                {
                    DoubleClickItem = item.Id.ToString() + ":" + (item.Group ?? "(null)");
                }
            }

            [Browsable(false)]
            public ICommand SelectionChangedCommand { get { return CreateCommand(SelectionChanged); } }
            private void SelectionChanged(object arg)
            {
                var items = arg as object[];
                if (items != null)
                {
                    SelectionChangedItem = "";
                    foreach (GridItem item in items)
                    {
                        SelectionChangedItem += item.Id.ToString() + ":" + (item.Group ?? "(null)");
                    }
                }
            }


            public DataGridSample()
            {
                DataGrid1 = GridItem.CreateData(10);
            }
        }

        [View(ViewControlType.Grid)]
        [ViewProperty("MinHeight", 150)]
        public class TreeViewSample : ViewModelBase
        {
            public class TreeViewNode : ViewModelBase
            {
                public string Name { get; set; }

                public bool IsSelected
                {
                    get { return _isSelected; }
                    set { _isSelected = value; OnPropertyChanged("IsSelected"); }
                }
                private bool _isSelected;


                public ObservableCollection<TreeViewNode> Children
                {
                    get
                    {
                        if (_children == null)
                        {
                            _children = new ObservableCollection<TreeViewNode>();
                            for (int i = 0; i < 5; i++)
                            {
                                _children.Add(new TreeViewNode { Name = "Data" + (cnt++).ToString() });
                            }
                        }
                        return _children;
                    }
                }
                private ObservableCollection<TreeViewNode> _children;
                private static int cnt = 0;

                public TreeViewNode GetSelectedNode()
                {
                    if (IsSelected) return this;
                    foreach (var child in Children)
                    {
                        var node = child.GetSelectedNode();
                        if (node != null) return node;
                    }
                    return null;
                }
            }

            public string SelectedName { get; set; }

            [View(ViewControlType.TreeView)]
            [ViewProperty(TreeViewControl.Properties.ItemsSource, "Children")]
            [ViewProperty(TreeViewControl.Properties.DisplayMember, "Name")]
            [ViewProperty(TreeViewControl.Properties.IsSelected, "IsSelected")]
            [ViewProperty(TreeViewControl.Properties.SelectedObject, "SelectedTreeViewNode")]
            [ViewProperty(TreeViewControl.Properties.SelectedItemChangedCommand, "SelectedItemChangedCommand")]
            public ObservableCollection<TreeViewNode> TreeItemList { get; set; }

            [Browsable(true)]
            public TreeViewNode SelectedTreeViewNode
            {
                get { return _selectedTreeViewNode; }
                set
                {
                    _selectedTreeViewNode = value;
                    OnPropertyChanged("SelectedTreeViewNode");
#if SILVERLIGHT
                    _selectedTreeViewNode.IsSelected = true;
#endif
                }
            }
            private TreeViewNode _selectedTreeViewNode;


            [Browsable(false)]
            public ICommand SelectedItemChangedCommand { get { return CreateCommand(SelectedItemChanged); } }
            public void SelectedItemChanged(object item)
            {

                var treeNode = item as TreeViewNode;
                if (treeNode != null)
                {
                    SelectedName = treeNode.Name;
                    OnPropertyChanged("SelectedName");
#if !SILVERLIGHT
                    SelectedTreeViewNode = treeNode;
#endif
                }
            }

            public TreeViewSample()
            {
                TreeItemList = new ObservableCollection<TreeViewNode>();
                TreeItemList.Add(new TreeViewNode { Name = "Root Node" });
            }

        }

        [View(ViewControlType.TabControl)]
        [ViewProperty(TabControlViewControl.Properties.TabStripPlacement, LayoutDock.Left)]
        public class TabControlSample : ViewModelBase
        {
            public class TabControlItem : ViewModelBase
            {
                public string Data1 { get; set; }
                public DateTime Data2 { get; set; }
                public bool Data3 { get; set; }
                public int Data4 { get; set; }
            }

            [Browsable(true)]
            public TabControlItem Item1 { get; set; }
            [Browsable(true)]
            [ViewProperty(ViewControl.Properties.Background, "Azure")]
            public TabControlItem Item2 { get; set; }
            [Browsable(true)]
            [ViewProperty(ViewControl.Properties.Background, "Gray")]
            public TabControlItem Item3 { get; set; }
            [Browsable(true)]
            public TabControlItem Item4 { get; set; }

        }

        [View(ViewControlType.StackPanel)]
        public class LiteralSample
        {
            [View(ViewControlType.Literal)]
#if !SILVERLIGHT
            [ViewProperty(LiteralViewControl.Properties.Literal, "<ContentControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ><Calendar /></ContentControl>")]
#else
            [ViewProperty(LiteralViewControl.Properties.Literal, "<ContentControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:sdk=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk\"><sdk:Calendar /></ContentControl>")]
#endif
            public string Literal1 { get; set; }
        }

        [View(ViewControlType.StackPanel)]
        [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public class UserControlSample : ViewModelBase
        {
            [View(typeof(SampleUserControl))]
            public class SampleUserControlViewModel : ViewModelBase
            {
                public string Input { get; set; }

                public string Output
                {
                    get { return _output; }
                    set { _output = value; OnPropertyChanged("Output"); }
                }
                private string _output;

                public ICommand Hello { get { return CreateCommand(() => Output = "Hello " + Input); } }
            }

            [Browsable(true)]
            [ViewProperty(UserControlViewControl.Properties.HorizontalAlignment, LayoutHorizontalAlignment.Stretch)]
            public SampleUserControlViewModel UserControl1 { get; set; }

            [Browsable(true)]
            [ViewProperty(UserControlViewControl.Properties.Width, 200)]
            [ViewProperty(UserControlViewControl.Properties.Background, "Azure")]
            [ViewProperty(UserControlViewControl.Properties.IsEnabled, "IsEnabled")]
            public SampleUserControlViewModel UserControl2 { get; set; }

            public bool IsEnabled
            {
                get { return _isEnabled; }
                set { _isEnabled = value; OnPropertyChanged("IsEnabled"); }
            }
            private bool _isEnabled;



            public UserControlSample()
            {
                UserControl1 = new SampleUserControlViewModel();
                UserControl2 = new SampleUserControlViewModel();
            }
        }

        [Browsable(true)]
        public LabelSample Label { get { return new LabelSample(); } }

        [Browsable(true)]
        public TextBoxSample TextBox { get { return new TextBoxSample(); } }

        [Browsable(true)]
        public ComboBoxSample ComboBox { get { return new ComboBoxSample(); } }

        [Browsable(true)]
        public ListBoxSample ListBox { get { return new ListBoxSample(); } }

        [Browsable(true)]
        public RadioButtonListSample RadioButton { get { return new RadioButtonListSample(); } }

        [Browsable(true)]
        public ItemsControlSample ItemsControl { get { return new ItemsControlSample(); } }

        [Browsable(true)]
        public CheckBoxSample CheckBox { get { return new CheckBoxSample(); } }

        [Browsable(true)]
        public DatePickerSample DatePicker { get { return new DatePickerSample(); } }

        [Browsable(true)]
        public ButtonSample Button { get { return _button; } }
        private ButtonSample _button = new ButtonSample();

        [Browsable(true)]
        public HyperlinkSample Hyperlink { get { return _hyperlink; } }
        private HyperlinkSample _hyperlink = new HyperlinkSample();

        [Browsable(true)]
        public HeaderSample Header { get { return new HeaderSample(); } }

        [Browsable(true)]
        public CanvasSample Canvas { get { return new CanvasSample(); } }

        [Browsable(true)]
        public StackPanelSample StackPanel { get { return new StackPanelSample(); } }

        [Browsable(true)]
        public GridSample Grid { get { return new GridSample(); } }

        [Browsable(true)]
        public DataGridSample DataGrid { get { return new DataGridSample(); } }

        [Browsable(true)]
        public TreeViewSample TreeView { get { return new TreeViewSample(); } }

        [Browsable(true)]
        public TabControlSample TabControl { get { return new TabControlSample(); } }

        [Browsable(true)]
        public LiteralSample Literal { get { return new LiteralSample(); } }

        [Browsable(true)]
        public UserControlSample UserControl { get { return _userControl; } }
        private UserControlSample _userControl = new UserControlSample();

        public SampleViewModel()
        {
            Button.ViewCommandNotified += new EventHandler<ViewCommandEventArgs>(ViewCommandNotifiedHandler);
            Hyperlink.ViewCommandNotified += new EventHandler<ViewCommandEventArgs>(ViewCommandNotifiedHandler);
        }

        void ViewCommandNotifiedHandler(object sender, ViewCommandEventArgs e)
        {
            ExecuteViewCommand(e.Command, e.Parameter);
        }
    }

}
